#ifndef GETVOLTAGES_HEADER_FLAG
#define GETVOLTAGES_HEADER_FLAG

// The included directories
#include <stdio.h> 		// Needed before NIDAQmx.h with MinGW
#include "NIDAQmx.h"
#include "mathlink.h"
#include "option.h"
#include "job.h"
#include <math.h>
#include <string>
#include <algorithm>
#include <sstream>
#include <map>
#include <vector>
#include<string>
#include <iostream>  // temp?
using namespace std;			// bad idea! put in both cpp files? use using declaration in cpp files

OutputJob* CreateOutputJob(persistJobHolder& pj, option& opt);  // const references?
void OutputWaveformDispatch(OutputJob* jptr, persistJobHolder& pjh, option& opt);  // const references?

/* class option
 * {
 * public:
 * 	option();
 * 	option(option &);
 * 	~option();
 * 	map<string, vector<int> > NIDAQConstants;
 * 	void loadNIDAQConstants(void);
 * 	map<string,long> L;
 * 	long getL(string name) {return L[name];}		// change to throw exception if name not found
 * 	map<string,double> D;
 * 	double getD(string name) {return D[name];}
 * 	map<string,string> S;
 * 	string getS(string name) {return S[name];}
 * 	map<string,double *> DArray;
 * 	map<string,long> DASize;
 * 	double* getDArray(string name) {return DArray[name];}
 * 	long	getDASize(string name) {return DASize[name];}
 * 	void createarray(string name, long size);
 * 	void fromMathematica(MLINK mlink);
 * 	void getNIDAQConstants(void);
 * 	std::string toString(const char* endline = "\n",const char* tab="\t");
 * };
 */

/*
extern int outputvoltage(float64 volts);	// should main declarations be here?
extern void getvoltagescpp(void);
extern void getvoltagescpp(const char * channels, int numchannels, double frequency,int samples,
					int terminalmode,double min, double max,int units, const char * clock,
					int activeedge, int samplemode, double timeout, int debug);
extern void getvoltages( int numSamples, double sampleFreq);
extern void getmultichvoltages( int numSamples, \
							   float64 sampleFreq);
extern void getvoltage_trig(int numSamples,double sampleFreq,double triggerLevel);
extern int outputwaveform(double *waveform,long waveformSize, double freq, double numPeriods);
extern void outputwaveformcpp(void);
extern int cleartask(int task);
extern void getvoltagessofttrig(void);
extern void getvoltagessoftwaretrig(void);
*/

void senderr(int32 errNum);
void checkerr(int32 errNum, long messagelevel = 1);

template<class T> void sendmessage(string message, T value, long messagelevel=1)
// template deffinition are different than function deffinitions the NEED to be
// it the header.
{
	if (messagelevel == 0)
		return;
	stringstream ss;
	ss << "Print[\"" << message << value << "\"];" << endl;
	MLEvaluateString(stdlink,(char * const) ss.str().c_str());
	return;
}
//class Job;		// declaration which doesn't mess up order

template<class T> 
void message(string message, T value1, Job* job, T value2 = ".",
			 string category = "general", int priority=4, long altmessagelevel=-1)
// template deffinition are different than function deffinitions the NEED to be
// it the header.
{
	long ml = 0;
	if (job == 0 && altmessagelevel < 0)
	{
		MLEvaluateString(stdlink,
			"Print[\"Either a valid job or alternate message level must be specified\"];");
		return;
	}
	else
		long ml = job->getoptL("messagelevel");  // only works on VC compiler with forward declaration
	if (ml == 0)
		return;
	stringstream ss;
	ss << "Print[\"" << message << value1 << " : " << value2 << "\"];" << endl;
	MLEvaluateString(stdlink,(char * const) ss.str().c_str());
	return;
}
//~ void bigerror(void);

#endif

